<?php

namespace Plugin\Device\Process;

use Common\Common;
use Hyperf\Coroutine\Coroutine;
use Hyperf\Process\AbstractProcess;
use Hyperf\Process\Annotation\Process;
use Plugin\Device\Repository\RdDeviceBroadcastServerRepository;
use Plugin\Device\Repository\RdDeviceSerialRepository;
use Plugin\Device\Service\IpBroadcastService;
use Plugin\EasyCVR\Service\EasyCVRService;

#[Process(name: 'broadcast-sync')]
class SyncDeviceProcess extends AbstractProcess
{

    public function isEnable($server): bool
    {
        return env('ENABLE_PROCESS');
    }

    public function handle(): void
    {
        Coroutine::create(function () {
            while (true) {
//                广播同步
                $servers = Common::container()->get(RdDeviceBroadcastServerRepository::class)->list();
                foreach ($servers as $server) {
                    try {
                        Common::container()->get(IpBroadcastService::class)
                            ->syncDeviceStatus($server->toArray());
                    } catch (\Throwable $e) {
                        Common::logException(__CLASS__, $e, 'sync device error server_id: ' . $server->id);
                    }
                }
//                摄像头同步
                try {
                    $service = Common::container()->get(EasyCVRService::class);
                    $deviceRepo = Common::container()->get(RdDeviceSerialRepository::class);
                    $deviceList = $service->devicesConfig(); //线上设备列表
                    $deviceData = $deviceRepo->getQuery()->get()->groupBy('device_serial')->toArray(); //数据库设备列表
                    if (isset($deviceList['Devices']) && is_array($deviceList['Devices'])) {
                        foreach ($deviceList['Devices'] as $device) {
                            $deviceID = intval($device['DeviceID']);
                            if (isset($deviceData[$deviceID])) {
                                $channelList = $service->channelsConfig($device['DeviceID']); // 线上通道列表
                                foreach ($channelList['Channels'] as $channel) {
                                    $channelData = array_values(array_filter($deviceData[$deviceID], function ($item) use ($channel){
                                        return $item['channel_no'] == $channel['ChannelID'];
                                    }))[0];
                                    $update = [];
                                    if ($channel['Online']) {
                                        if ($channelData['online'] != 1) {
                                            $update['online'] = 1;
                                        }
                                    } else {
                                        if ($channelData['online'] != 2) {
                                            $update['online'] = 2;
                                        }
                                    }
                                    if (empty($channelData['url']) && $channel['Online'] + 1 == 2) {
                                        $stream = $service->channelStreamAllAddr(
                                            strval($channelData['device_serial']),
                                            strval($channelData['channel_no'])
                                        );
                                        $update['url'] = [
                                            'FLV' => $stream['FLV'],
                                            'RTMP' => $stream['RTMP'],
                                            'HLS' => $stream['HLS'],
                                            'RTSP' => $stream['RTSP'],
                                            'FMP4' => $stream['FMP4'],
                                            'WS_FLV' => $stream['WS_FLV'],
                                            'WS_FMP4' => $stream['WS_FMP4'],
                                            'WEBRTC' => $stream['WEBRTC'],
                                        ];
                                    }
                                    if (!empty($update)) {
                                        $deviceRepo->updateById($channelData['id'], $update);
                                    }
                                }

                            }

                        }
                    }
                } catch (\Throwable $e) {
                    Common::logException(__CLASS__, $e, 'sync camera error');
                }
                Coroutine::sleep(300);
            }
        });
    }
}